package top.itaso.app.room;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;

import top.itaso.app.MyApplication;
import top.itaso.app.room.dao.UserDao;
import top.itaso.app.room.dao.WifiScanResultDao;
import top.itaso.app.room.entity.UserEntity;
import top.itaso.app.room.entity.WifiScanResultEntity;
import top.itaso.lib.alog.ALog;

/**
 * @Description: Jetpack Room 组件初始化过程，包含数据库升级、降级等
 * https://developer.android.google.cn/training/data-storage/room?hl=zh_cn
 * 1.在编译时，Room 会将数据库的架构信息导出为 JSON 文件（默认exportSchema = true导出架构）。要导出架构，请在 build.gradle 文件中设置 room.schemaLocation 注释处理器属性（设置将json存放的位置）。
 * @Author itsdf07
 * @E-Mail 923255742@qq.com
 * @Gitee https://gitee.com/itsdf07
 * @Date 2022/1/10
 */
@Database(entities = {UserEntity.class, WifiScanResultEntity.class}, version = 2, exportSchema = true)
//exportSchema-是否生成schema文件，schema文件中包含的是表结构和信息
public abstract class AppDatabase extends RoomDatabase {
    private static final String TAG = AppDatabase.class.getSimpleName();
    private static AppDatabase instance;
    private static final String DB_NAME = "itaso.db";

    public abstract UserDao userDao();

    public abstract WifiScanResultDao wifiScanResultDao();

    public static AppDatabase getInstance() {
        if (instance == null) {
            ALog.vTag(TAG, "数据库初始化中");
            synchronized (AppDatabase.class) {
                if (instance == null) {
                    instance = buildDataBase();
                }
            }
            ALog.vTag(TAG, "数据库初始化完成");
        }
        return instance;
    }

    private static AppDatabase buildDataBase() {
        ALog.vTag(TAG, "Room 数据库单例:%s", instance);
        return Room.databaseBuilder(MyApplication.getContext(), AppDatabase.class, DB_NAME)
                .addCallback(sRoomDatabaseCallback)
                .allowMainThreadQueries()//是否允许在主线程上操作数据库，默认false。
//                .fallbackToDestructiveMigration()// 数据库版本异常时 会清空原来的数据  然后转到目前版本
//                .createFromAsset("资源文件中的初始数据库")// 预填充数据库  初始数据
                .addMigrations(MIGRATION_1_2)// 数据库升级时，可以追加多个
                .build();
    }

    //数据库创建和打开的事件会回调到这里，可以再次操作数据库
    private static Callback sRoomDatabaseCallback = new Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            ALog.dTag(TAG, "db.version:%s", db.getVersion());
        }

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
            ALog.dTag(TAG, "db.version:%s", db.getVersion());
        }
    };

    //数据迁移可参考：https://blog.csdn.net/yonghuming_jesse/article/details/98037118
    private static Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            ALog.dTag(TAG, "数据库从1升级到2");
            database.execSQL("ALTER TABLE users ADD COLUMN _sex INTEGER NOT NULL DEFAULT 1");// 添加表字段
        }
    };
}
